﻿#define _CRT_SECURE_NO_WARNINGS 1
HTTP常⻅Header
• Content - Type: 数据类型(text / html等)
• Content - Length : Body的⻓度
• Host : 客⼾端告知服务器, 所请求的资源是在哪个主机的哪个端⼝上;
• User - Agent: 声明⽤⼾的操作系统和浏览器版本信息;
• Referer : 当前⻚⾯是从哪个⻚⾯跳转过来的;
• Location : 搭配3xx状态码使⽤, 告诉客⼾端接下来要去哪⾥访问;
• Cookie : 在客⼾端存储少量信息.通常⽤于实现会话(session)的功能;
• connection：

-------------------------------- -
Content - Type对照表引入到unodered_map中，构造函数中完成即可，我们只需显式的插入几个常用的即可；只需要注意当我们的k为unkonw的事后，v为text / html，所以当我们代码中找_path的后缀没找到，就让后缀为.unkonw，这样kv映射就是text / html

-------------------------------- -
频繁的bind同一个端口号 会出错的原因：
和TCP的四次挥手有关，导致端口号仍然在被使用，服务器无法再次bind端口号，所以binderror，今天重点不在于问题如何产生，而是问题如何解决

我们需要在封装套接字的文件中的基类新增一个接口，设置套接字地址复用
SetSocketAddrReuse(); 在内部调用setsockopt接口。setsockopt意为设置套接字属性：

int setsockopt(int sockfd, int level, int optname,
	const void* optval, socklen_t optlen);
参数：套接字，哪一层，选项名字，选项值，选项长度

void SetSockgetAddrReuse() override
{
	int opt = 1;
	::setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
}

SetSockgetAddrReuse()在创建套接字之后立即使用

设置套接字地址复用是必要的操作，避免服务器挂掉了，影响到了之前的所有已连接的链接，没有地址复用，只能进行更换端口号，服务器当然不能随意更改端口号，比如双11下的tb更换端口号，影响巨大
-------------------------------- -
• Host : 客⼾端告知服务器, 所请求的资源是在哪个主机的哪个端⼝上;
如：Host: 8.137.19.140 : 8888

Q：服务端不就是主机吗？为什么还需要主机IP字段？
A：有可能我们接收到我们请求的服务器并不是最终服务器，而是一个中间服务器，也叫作代理服务器，代理服务器接收到字后，通过Host字段得知是向最终服务器发送的请求，代理服务器会自己充当客户端向最终服务器发送请求，然后接收到响应，再以服务器的身份向客户端返回响应

-------------------------------- -
• Referer : 当前⻚⾯是从哪个⻚⾯跳转过来的;
Referer:http://8.137.19.140:8888/2.html

比如a标记的跳转功能，当你从首页跳转到另一个页面的时候，此时请求信页面的报文中的请求报头中的Referer:就会记录你是从首页跳过来的，

意义：网站的回退？禁止某一个网页地址的访问(不做响应)，等......


-------------------------------- -
• Location : 搭配3xx状态码使⽤, 告诉客⼾端接下来要去哪⾥访问;
后面说

-------------------------------- -
• Cookie : 在客⼾端存储少量信息.通常⽤于实现会话(session)的功能;
加餐课说，下面会简略地用代码体现一下

-------------------------------- -
•connection(长链接)：⽤于控制和管理客⼾端与服务器之间的连接状态
Connection : keep - alive：表⽰希望保持连接以复⽤TCP连接
Connection : close ：表⽰请求 / 响应完成后，应该关闭TCP连接

比如一个网站中的资源很多，图片音频都不止一个，所以我们每次获取资源都需要发送请求，而发送请求的本质就是TCP客户端发送连接，所以会造成众多的TCP的connect的连接请求，这不好；所以Connection 字段可以⽤于管理持久连接（也称为⻓连接）。持久连接允许客⼾端和服务器在请求 / 响应完成后不⽴即关闭TCP连接，以便在同⼀个连接上发送多个请求和接收多个响应。(一个TCP连接处理多个请求的高效场景)

注：在HTTP / 1.1协议中是默认长连接的，在HTTP / 1.0中不是

我们之前的计算器就是1.1版本，模拟的长连接，我们的请求是堆积的，我们不断的读取请求，不断的做出回应

而我们今天的代码是1.0版本，不是长连接，因为我们的服务端代码中的HandlerSock接口中，读取到了请求后，处理后返回应答后，就立马关闭了sockfd；

而长连接读取请求的时候，就要处理粘报的问题，计算机中是通过len字段，而http中自带 Content - Length字段


-------------------------------- -
其余字段的说明 在wps中有
Accept：客⼾端可接受的响应内容类型
Accept - Encoding：客⼾端⽀持的数据压缩格式
Accept - Language：客⼾端可接受的语⾔类型

Accept - Encoding：我们代码无法体现，在浏览器中的图片过大或者视频过大就会事先进行压缩

-------------------------------- -
浏览器是会对资源做缓存的，这就是为什么第一次访问网页速度慢，后面就快了，这个是浏览器的策略

-------------------------------- -
状态码的理解：

各种非正常状况都要清晰的反映给客户端，让客户端知道错误原因

3xx：看一半让你充会员 或者让你登录 类似的操作
4xx：比如404的错误 叫作客户端错误 不要以为是服务端没有资源的错误，因为这是不合理的请求 ，错在客户端，你跟你爸要1个亿 谁错？
5xx：服务端错误，内部文件打开错误，线程或进程创建错误等，这种才叫服务器错误

注：大多数的5xx错误，一般会以4xx的错误展现，防止黑客测试服务端的错误所在，全都是4xx，无法测试，不让外人知道服务端错误的触发场景

Q：HTTP协议规定的状态码，还能不按要求返回吗？
A：是的，各家浏览器公司互相竞争，谁也不想让自己的服务端错误场景被测试出来，而且就算是错误返回2xx也是可以的，因为这只是让客户端看到的罢了